package com.iraeta.service.basic.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.iraeta.common.ServiceException;
import com.iraeta.dao.main.*;
import com.iraeta.entity.main.*;
import com.iraeta.entity.main.type.ExcelSheetBean;
import com.iraeta.entity.main.type.PlanZq;
import com.iraeta.entity.main.vo.ErpCurrentStoreVo;
import com.iraeta.service.basic.CsSnapshotService;
import com.iraeta.uitl.ExcelUtil;
import com.iraeta.uitl.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CsSnapshotServiceImpl implements CsSnapshotService {
    @Autowired
    ErpCsSnapshotDao erpCsSnapshotDao;
    @Autowired
    ErpCsSnapshotRecordDao erpCsSnapshotRecordDao;
    @Autowired
    ErpCsSnapshotCangkuDao erpCsSnapshotCangkuDao;
    @Autowired
    PlanDao planDao;
    @Autowired
    ErpCangkuDao erpCangkuDao;

    @Transactional
    @Override
    public void createCsSnapshot(ErpCsSnapshot erpCsSnapshot, JSONArray cwhcodes, int nowMonth) {
        List<String> cwhcodeList = new ArrayList<>();
        for(int i =0; i<cwhcodes.size(); i++){
            cwhcodeList.add(cwhcodes.getString(i));
        }
        String cwhCodeIdStr = Util.parseListToSqlString(cwhcodeList);

        Date beginJcDate = null;
        Date endJcDate = null;
        Plan plan = erpCsSnapshot.getPlanid() > 0 ? planDao.selectByPrimaryKey(erpCsSnapshot.getPlanid()) : new Plan();
        if(erpCsSnapshot.getPlanid() > 0){  //如果有planId 则需要看plan定义 看填报的数据是否满足要求
            erpCsSnapshot.setCdefine1(planDao.selectByPrimaryKey(erpCsSnapshot.getPlanid() ).getTitle());
            Date now = new Date();
            int year = DateUtil.year(now);
            int month = DateUtil.month(now) + 1;
            int quarter = DateUtil.quarter(now); //第几季度
            if(plan.getZq() == PlanZq.once){
                beginJcDate = DateUtil.parseDate(plan.getCdefine1());
                endJcDate = DateUtil.parseDate(plan.getCdefine2());
            }else if (plan.getZq() == PlanZq.month){
                beginJcDate = DateUtil.parseDate(year + "-" + month + "-" + plan.getCdefine1());
                endJcDate = DateUtil.parseDate(year + "-" + month + "-" + plan.getCdefine2());
            }else{
                int calcMonth = (quarter - 1) * 3 + Integer.parseInt(plan.getCdefine3());
                beginJcDate = DateUtil.parseDate(year + "-" + calcMonth + "-" + plan.getCdefine1());
                endJcDate = DateUtil.parseDate(year + "-" + calcMonth + "-" + plan.getCdefine2());
            }
            endJcDate = DateUtil.offsetDay(endJcDate, 1);
            if(!(beginJcDate.getTime() <= erpCsSnapshot.getCreatetime().getTime() &&  erpCsSnapshot.getCreatetime().getTime() < endJcDate.getTime())){
                throw new RuntimeException("不能在盘点周期外生成盘点记录");
            }
            int csCount = erpCsSnapshotRecordDao.selectBatchBy_erp_current_store(cwhCodeIdStr, DateUtil.formatDate(beginJcDate), DateUtil.formatDate(endJcDate));
            if(csCount > 0){
                throw new RuntimeException("盘点填报日期必须在盘点周期内");
            }
            for (String cwhcode : cwhcodeList) {
                ErpCsSnapshot hasErpCsSnapshot = erpCsSnapshotDao.selectLastTbRecord(plan.getId(), cwhcode, DateUtil.formatDate(beginJcDate), DateUtil.formatDate(endJcDate));
                if(hasErpCsSnapshot != null){
                    throw new RuntimeException("仓库编号[" + cwhcode +"]已在本周起填报了盘点记录，不能重复填写");
                }
            }
        }
        //保存主表
        erpCsSnapshotDao.insert(erpCsSnapshot);
        if(erpCsSnapshot.getId() == 0){
            throw new ServiceException("创建盘点记录失败未知错误");
        }
        //同步record数据
        erpCsSnapshotRecordDao.addBatchBy_erp_current_store(erpCsSnapshot.getId(), cwhCodeIdStr);
        if(nowMonth == 1){  //如果是只需要本月的盘点数据生成盘点记录
            erpCsSnapshotRecordDao.update_erp_current_store(erpCsSnapshot.getId(), DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") );
        }
        //保存记录的仓库表， 并根据仓库计算这次的 盘点质量
        for (String cwhcode : cwhcodeList) {
            BigDecimal chouchalv = new BigDecimal(0);
            BigDecimal chongfulv = new BigDecimal(0);
            if(erpCsSnapshot.getPlanid() > 0){  //如果有盘点计划
                //这里需要计算这个填报的质量
                List<ErpCsSnapshotRecord> erpCsSnapshotRecordList_All = erpCsSnapshotRecordDao.selectAllSIDRecord(erpCsSnapshot.getId(), cwhcode);
                List<ErpCsSnapshotRecord> erpCsSnapshotRecordList_Tb = erpCsSnapshotRecordDao.selectHasTbSIDRecord(erpCsSnapshot.getId(), cwhcode);
                BigDecimal all = new BigDecimal(erpCsSnapshotRecordList_All.size());
                BigDecimal tb = new BigDecimal(erpCsSnapshotRecordList_Tb.size());
                chouchalv = tb.multiply(new BigDecimal("100")).divide(all,2,RoundingMode.HALF_UP);
                //if(plan.getZq() == PlanZq.once){}  一次性提报的肯定不会重复

                Date startDate = null;
                Date endDate = null;
                if(plan.getZq() == PlanZq.month){
                    startDate = DateUtil.offsetMonth(beginJcDate, -1);
                    endDate = DateUtil.offsetMonth(endJcDate, -1);
                }
                if(plan.getZq() == PlanZq.jidu){
                    startDate = DateUtil.offsetMonth(beginJcDate, -3);
                    endDate = DateUtil.offsetMonth(endJcDate, -3);
                }
                ErpCsSnapshot lastErpCsSnapshot = erpCsSnapshotDao.selectLastTbRecord(plan.getId(), cwhcode, DateUtil.formatDate(startDate), DateUtil.formatDate(endDate));
                if(lastErpCsSnapshot == null){      //第一次提报肯定不会重复
                    chongfulv = new BigDecimal("0");
                } else {
                    List<ErpCsSnapshotRecord> erpCsSnapshotRecordList_Tb_Last = erpCsSnapshotRecordDao.selectHasTbSIDRecord(lastErpCsSnapshot.getId(), cwhcode);
                    List<String> cwhcode_tb = erpCsSnapshotRecordList_Tb.stream().map(ErpCsSnapshotRecord::getCinvcode).collect(Collectors.toList());
                    List<String> cwhcode_tb_last = erpCsSnapshotRecordList_Tb_Last.stream().map(ErpCsSnapshotRecord::getCinvcode).collect(Collectors.toList());
                    List<String> cwhcode_jj = cwhcode_tb.stream().filter(cwhcode_tb_last::contains).collect(Collectors.toList());
                    chongfulv = new BigDecimal(cwhcode_jj.size()).multiply(new BigDecimal("100")).divide(new BigDecimal(cwhcode_tb.size()),2,RoundingMode.HALF_UP);
                }
            }
            ErpCangku erpCangku = erpCangkuDao.selectByCode(cwhcode);
            ErpCsSnapshotCangku erpCsSnapshotCangku = new ErpCsSnapshotCangku(erpCsSnapshot.getId(), erpCangku.getId(), cwhcode);
            erpCsSnapshotCangku.setChouchalv(chouchalv);
            erpCsSnapshotCangku.setChongfulv(chongfulv);
            erpCsSnapshotCangkuDao.insert(erpCsSnapshotCangku);
        }
    }

    @Override
    public List<ErpCsSnapshot> listErpCsSnapshot(String title, String createuser) {
        return erpCsSnapshotDao.selectErpCsSnapshot(title, createuser);
    }

    @Override
    public List<ErpCsSnapshot> listErpCsSnapshotSelf(String title, String createuser) {
        return erpCsSnapshotDao.selectErpCsSnapshotSelf(title, createuser);
    }

    @Override
    public List<ErpCsSnapshot> listErpCsSnapshotPlan(Integer planId, String createUser, String startDate, String endDate) {
        return erpCsSnapshotDao.selectErpCsSnapshotPlan(planId, createUser, startDate, endDate);
    }

    @Override
    public List<ErpCsSnapshotRecord> listErpCsSnapshotRecord(ErpCurrentStoreVo erpCurrentStoreVo) {
        return erpCsSnapshotRecordDao.selectByCondition(erpCurrentStoreVo);
    }

    @Override
    public List<HashMap<String, Object>> listErpCangku(Integer ssId) {
        return erpCsSnapshotRecordDao.listErpCangku(ssId);
    }

    @Override
    public void exportErpCurrentStore(String filePath, List<ErpCsSnapshotRecord> erpCsSnapshotRecordList) {
        List<String> titles = new ArrayList<>();
        titles.add("仓库名称");
        titles.add("存货编码");
        titles.add("存货名称");
        titles.add("规格型号");
        titles.add("单位名称");
        titles.add("盘点时现存量");
        titles.add("盘点数量");
        titles.add("盘亏盘盈");
        titles.add("盘点人员");
        titles.add("盘点时间");
        Map<String, List<ErpCsSnapshotRecord>> ErpCsSnapshotRecordGroup = erpCsSnapshotRecordList.stream().collect(Collectors.groupingBy(ErpCsSnapshotRecord::getCwhname));
        List<ExcelSheetBean> excelSheetBeanList = new ArrayList<>();
        for(String cwhName : ErpCsSnapshotRecordGroup.keySet()){
            ExcelSheetBean excelSheetBean = new ExcelSheetBean();
            excelSheetBean.setSheetName(cwhName);
            excelSheetBean.setTitles(titles);
            List<List<String>> contents = new ArrayList<>();
            List<ErpCsSnapshotRecord> cwhErpCsSnapshotRecords = ErpCsSnapshotRecordGroup.get(cwhName);
            for (ErpCsSnapshotRecord cwhErpCsSnapshotRecord : cwhErpCsSnapshotRecords) {
                List<String> content = new ArrayList<>();
                String czquantity = "";
                String iquantity = "";
                if(cwhErpCsSnapshotRecord.getCzquantity() != null){
                    if(cwhErpCsSnapshotRecord.getCzquantity().compareTo(new BigDecimal("0")) != 0){
                        czquantity =  cwhErpCsSnapshotRecord.getCzquantity().stripTrailingZeros().toPlainString();
                    }else{
                        czquantity = "0";
                    }
                    if(cwhErpCsSnapshotRecord.getPdquantity() != null ){
                        iquantity = cwhErpCsSnapshotRecord.getPdquantity().subtract(cwhErpCsSnapshotRecord.getCzquantity()).stripTrailingZeros().toPlainString();
                    }
                }else{
                    iquantity = cwhErpCsSnapshotRecord.getIquantity() == null ? "" : cwhErpCsSnapshotRecord.getIquantity().stripTrailingZeros().toPlainString();
                }
                content.add(cwhErpCsSnapshotRecord.getCwhname()  == null ? "" : cwhErpCsSnapshotRecord.getCwhname());
                content.add(cwhErpCsSnapshotRecord.getCinvcode()  == null ? "" : cwhErpCsSnapshotRecord.getCinvcode());
                content.add(cwhErpCsSnapshotRecord.getCinvname()  == null ? "" : cwhErpCsSnapshotRecord.getCinvname());
                content.add(cwhErpCsSnapshotRecord.getCinvstd() == null ? "" : cwhErpCsSnapshotRecord.getCinvstd());
                //content.add(cwhErpCsSnapshotRecord.getCbatch() == null ? "" : cwhErpCsSnapshotRecord.getCbatch());
                content.add(cwhErpCsSnapshotRecord.getCcomunitname() == null ? "" : cwhErpCsSnapshotRecord.getCcomunitname());
                content.add(iquantity);
                content.add(cwhErpCsSnapshotRecord.getPdquantity() == null ? "" : cwhErpCsSnapshotRecord.getPdquantity().stripTrailingZeros().toPlainString());
                content.add(czquantity);
                content.add(cwhErpCsSnapshotRecord.getPduser() == null ? "" : cwhErpCsSnapshotRecord.getPduser());
                content.add(cwhErpCsSnapshotRecord.getLasttbdate() == null ? "" : DateUtil.formatDateTime(cwhErpCsSnapshotRecord.getLasttbdate()));
                contents.add(content);
            }
            excelSheetBean.setContents(contents);
            excelSheetBeanList.add(excelSheetBean);
        }
        try {
            ExcelUtil.writeExcel(filePath, excelSheetBeanList);
        }catch (IOException e){
            throw new ServiceException("盘点记录数据写入excel报错");
        }
    }
}
